package validator

import (
	"errors"
	"fmt"
	"reflect"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	enTranslations "github.com/go-playground/validator/v10/translations/en"
	zhTranslations "github.com/go-playground/validator/v10/translations/zh"
)

// Trans 全局翻译器
var Trans ut.Translator

// ValidationError 验证错误结构
type ValidationError struct {
	Field   string `json:"field"`
	Tag     string `json:"tag"`
	Value   string `json:"value"`
	Message string `json:"message"`
}

// ValidationErrors 验证错误列表
type ValidationErrors []ValidationError

// Error 实现error接口
func (ve ValidationErrors) Error() string {
	var messages []string
	for _, err := range ve {
		messages = append(messages, err.Message)
	}
	return strings.Join(messages, "; ")
}

// GetFieldErrors 获取字段错误详情
func (ve ValidationErrors) GetFieldErrors() map[string]string {
	fieldErrors := make(map[string]string)
	for _, err := range ve {
		fieldErrors[err.Field] = err.Message
	}
	return fieldErrors
}

// Init 初始化验证器翻译器
func Init(locale string) error {
	v, ok := binding.Validator.Engine().(*validator.Validate)
	if !ok {
		return errors.New("获取验证器引擎失败")
	}

	// 注册JSON标签名获取函数
	v.RegisterTagNameFunc(func(field reflect.StructField) string {
		jsonTag := field.Tag.Get("json")
		if jsonTag == "" || jsonTag == "-" {
			return field.Name
		}
		
		// 处理json标签，只取第一部分
		parts := strings.SplitN(jsonTag, ",", 2)
		return parts[0]
	})

	// 初始化翻译器
	zhLocale := zh.New()
	enLocale := en.New()
	uni := ut.New(enLocale, zhLocale, enLocale)

	// 获取翻译器
	var found bool
	Trans, found = uni.GetTranslator(locale)
	if !found {
		return fmt.Errorf("获取翻译器失败: %s", locale)
	}

	// 注册默认翻译
	switch locale {
	case "zh":
		return zhTranslations.RegisterDefaultTranslations(v, Trans)
	case "en":
		return enTranslations.RegisterDefaultTranslations(v, Trans)
	default:
		return enTranslations.RegisterDefaultTranslations(v, Trans)
	}
}

// ValidateStruct 验证结构体
func ValidateStruct(obj interface{}) ValidationErrors {
	v := binding.Validator.Engine().(*validator.Validate)
	err := v.Struct(obj)
	
	if err == nil {
		return nil
	}

	validationErrs, ok := err.(validator.ValidationErrors)
	if !ok {
		return ValidationErrors{{
			Field:   "unknown",
			Tag:     "unknown",
			Value:   "",
			Message: "参数验证失败",
		}}
	}

	return translateValidationErrors(validationErrs)
}

// ValidateJSON 验证JSON请求
func ValidateJSON[T any](c *gin.Context) (*T, ValidationErrors) {
	var obj T
	
	// 绑定JSON数据
	if err := c.ShouldBindJSON(&obj); err != nil {
		// 检查是否是验证错误
		if validationErrs, ok := err.(validator.ValidationErrors); ok {
			return nil, translateValidationErrors(validationErrs)
		}
		
		// 其他绑定错误（如JSON格式错误）
		return nil, ValidationErrors{{
			Field:   "request_body",
			Tag:     "json",
			Value:   "",
			Message: "JSON格式错误: " + err.Error(),
		}}
	}

	// 再次验证结构体（防止某些验证规则被跳过）
	if validationErrs := ValidateStruct(&obj); validationErrs != nil {
		return nil, validationErrs
	}

	return &obj, nil
}

// ValidateQuery 验证查询参数
func ValidateQuery[T any](c *gin.Context) (*T, ValidationErrors) {
	var obj T
	
	// 绑定查询参数
	if err := c.ShouldBindQuery(&obj); err != nil {
		if validationErrs, ok := err.(validator.ValidationErrors); ok {
			return nil, translateValidationErrors(validationErrs)
		}
		
		return nil, ValidationErrors{{
			Field:   "query_params",
			Tag:     "bind",
			Value:   "",
			Message: "查询参数绑定错误: " + err.Error(),
		}}
	}

	// 验证结构体
	if validationErrs := ValidateStruct(&obj); validationErrs != nil {
		return nil, validationErrs
	}

	return &obj, nil
}

// ValidateForm 验证表单数据
func ValidateForm[T any](c *gin.Context) (*T, ValidationErrors) {
	var obj T
	
	// 绑定表单数据
	if err := c.ShouldBind(&obj); err != nil {
		if validationErrs, ok := err.(validator.ValidationErrors); ok {
			return nil, translateValidationErrors(validationErrs)
		}
		
		return nil, ValidationErrors{{
			Field:   "form_data",
			Tag:     "bind",
			Value:   "",
			Message: "表单数据绑定错误: " + err.Error(),
		}}
	}

	// 验证结构体
	if validationErrs := ValidateStruct(&obj); validationErrs != nil {
		return nil, validationErrs
	}

	return &obj, nil
}

// translateValidationErrors 翻译验证错误
func translateValidationErrors(validationErrs validator.ValidationErrors) ValidationErrors {
	var errors ValidationErrors
	
	translatedErrors := validationErrs.Translate(Trans)
	
	for _, err := range validationErrs {
		fieldName := err.Field()
		
		// 移除结构体前缀
		if dotIndex := strings.LastIndex(fieldName, "."); dotIndex != -1 {
			fieldName = fieldName[dotIndex+1:]
		}
		
		errors = append(errors, ValidationError{
			Field:   fieldName,
			Tag:     err.Tag(),
			Value:   fmt.Sprintf("%v", err.Value()),
			Message: translatedErrors[err.Namespace()],
		})
	}
	
	return errors
}

// RegisterCustomValidation 注册自定义验证规则
func RegisterCustomValidation(tag string, fn validator.Func) error {
	v := binding.Validator.Engine().(*validator.Validate)
	return v.RegisterValidation(tag, fn)
}

// RegisterCustomTranslation 注册自定义翻译
func RegisterCustomTranslation(tag string, message string) error {
	v := binding.Validator.Engine().(*validator.Validate)
	
	// 注册翻译
	err := v.RegisterTranslation(tag, Trans, func(ut ut.Translator) error {
		return ut.Add(tag, message, true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T(tag, fe.Field())
		return t
	})
	
	return err
}